gusucode.com > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序 > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序/code/Explorer/CJMetaFileButton.cpp

    // CJMetaFileButton.cpp : implementation file
//
// Copyright ? 1999 Ian Brumby
//
// This source code may be used in compiled form in any way you desire. 
// Source file(s) may be redistributed unmodified by any means PROVIDING
// they are not sold for profit without the authors expressed written consent,
// and providing that this notice and the authors name and all copyright
// notices remain intact.
//
// ==========================================================================  
// HISTORY:	  
// ==========================================================================  
//			1.20	21 Apr 1999	- Initial release.
// ==========================================================================  
/////////////////////////////////////////////////////////////////////////////
/****************************************************************************
 *
 * $Date: 10/31/99 11:04p $
 * $Revision: 6 $
 * $Archive: /CodeJock/CJLibrary/CJMetaFileButton.cpp $
 *
 * $History: CJMetaFileButton.cpp $
 * 
 * *****************  Version 6  *****************
 * User: Kirk Stowell Date: 10/31/99   Time: 11:04p
 * Updated in $/CodeJock/CJLibrary
 * Overrode OnEraseBkgnd(...) and OnPaint() for flicker free drawing.
 * 
 * *****************  Version 5  *****************
 * User: Kirk Stowell Date: 10/25/99   Time: 10:52p
 * Updated in $/CodeJock/CJLibrary
 * Modified resource include for static builds.
 * 
 * *****************  Version 4  *****************
 * User: Kirk Stowell Date: 10/24/99   Time: 12:01a
 * Updated in $/CodeJock/CJLibrary
 * Fixed potential resource and memory leak problems.
 * 
 * *****************  Version 3  *****************
 * User: Kirk Stowell Date: 10/14/99   Time: 12:41p
 * Updated in $/CodeJock/CJLibrary
 * Added source control history to file header.
 *
 ***************************************************************************/
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CJResource.h"
#include "CJMetaFileButton.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCJMetaFileButton

CCJMetaFileButton::CCJMetaFileButton()
{
}

CCJMetaFileButton::~CCJMetaFileButton()
{
}

void CCJMetaFileButton::SetMetaFiles(HENHMETAFILE hMetaFile,
	HENHMETAFILE hMetaFileSel, HENHMETAFILE hMetaFileFocus, HENHMETAFILE hMetaFileDisabled)
{
	m_hEnhMetaFile         = hMetaFile;
	m_hEnhMetaFileSel      = hMetaFileSel;
	m_hEnhMetaFileFocus    = hMetaFileFocus;
	m_hEnhMetaFileDisabled = hMetaFileDisabled;
}


BEGIN_MESSAGE_MAP(CCJMetaFileButton, CButton)
	//{{AFX_MSG_MAP(CCJMetaFileButton)
	ON_WM_LBUTTONDBLCLK()
	ON_WM_ERASEBKGND()
	ON_WM_PAINT()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCJMetaFileButton message handlers

void CCJMetaFileButton::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	// Fix for the double click problem with owner drawn buttons
	POINT pt;
	::GetCursorPos(&pt);
	::MapWindowPoints(NULL, (HWND)(m_hWnd), &pt, 1);
	::SendMessage((HWND)(m_hWnd), WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));	
	CButton::OnLButtonDblClk(nFlags, point);
}

void CCJMetaFileButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
	ASSERT(lpDrawItemStruct != NULL);

	// define some temporary variables.
	CDC*  pDC	 = CDC::FromHandle( lpDrawItemStruct->hDC );
	CRect rcItem = lpDrawItemStruct->rcItem;
	int   nState = lpDrawItemStruct->itemState;

	// Paint the background.
	pDC->FillSolidRect(rcItem, ::GetSysColor(COLOR_3DFACE));
	
	// draw 3D button outline
	CPen penOutline(PS_SOLID, 1, GetSysColor(COLOR_BTNTEXT));
	CPen penLight(PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
	CPen penDark(PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
	CPen* pOldPen = NULL;

	if (nState & ODS_SELECTED)
	{
		pOldPen = pDC->SelectObject(&penDark);
		pDC->MoveTo(0, rcItem.bottom - 1);
		pDC->LineTo(0, 1);
		pDC->LineTo(rcItem.right - 1, 1);
	}
	else
	{
		pOldPen = pDC->SelectObject(&penLight);
		pDC->MoveTo(0, rcItem.bottom - 2);
		pDC->LineTo(0, 1);
		pDC->LineTo(rcItem.right - 2, 1);
		pDC->SelectObject(&penDark);
		pDC->MoveTo(0, rcItem.bottom - 1);
		pDC->LineTo(rcItem.right - 2, rcItem.bottom - 1);
		pDC->LineTo(rcItem.right - 2, 0);
		pDC->MoveTo(1, rcItem.bottom - 2);
		pDC->LineTo(rcItem.right - 3, rcItem.bottom - 2);
		pDC->LineTo(rcItem.right - 3, 1);
	}
	pDC->SelectObject(&penOutline);
	pDC->MoveTo(0, 0);
	pDC->LineTo(rcItem.right - 1, 0);
	pDC->LineTo(rcItem.right - 1, rcItem.bottom);
	
	HENHMETAFILE hMetaFile = m_hEnhMetaFile;
	if ((nState & ODS_SELECTED) && m_hEnhMetaFileSel != NULL)
		hMetaFile = m_hEnhMetaFileSel;
	else if ((nState & ODS_FOCUS) && m_hEnhMetaFileFocus != NULL)
		hMetaFile = m_hEnhMetaFileFocus;   // third image for focused
	else if ((nState & ODS_DISABLED) && m_hEnhMetaFileDisabled != NULL)
		hMetaFile = m_hEnhMetaFileDisabled;   // last image for disabled
	
	ASSERT(hMetaFile != NULL);
	
	CRect rcBounds(5,4,0,0);
	int iButtonHeight = rcItem.Height();
	if (iButtonHeight > 15)
		iButtonHeight = 15;
	else if (iButtonHeight < 11)
		iButtonHeight = 11;
	int iArrowWidth = (iButtonHeight / 2) - 3;
	rcBounds.right = rcBounds.left + iArrowWidth - 1;
	rcBounds.bottom = rcBounds.top + (iArrowWidth * 2) - 2;
	
	if (nState & ODS_SELECTED)
		rcBounds += CPoint(1, 1);
	pDC->PlayMetaFile(hMetaFile, rcBounds);

	// fix potential resource leak - KStowell - 10-21-99
	pDC->SelectObject(pOldPen);
	penOutline.DeleteObject();
	penLight.DeleteObject();
	penDark.DeleteObject();
}

BOOL CCJMetaFileButton::OnEraseBkgnd(CDC* pDC) 
{
	// KStowell - overridden for flicker-free drawing.
	UNUSED_ALWAYS(pDC);
	return TRUE;
}

void CCJMetaFileButton::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// KStowell - Get the client rect.
	CRect rcClient, rcClip;
	dc.GetClipBox( &rcClip );
	GetClientRect( &rcClient );

	// KStowell - Create a memory device-context. This is done to help reduce
	// screen flicker, since we will paint the entire control to the
	// off screen device context first.
	CDC memDC;
	CBitmap bitmap;
	memDC.CreateCompatibleDC(&dc);
	bitmap.CreateCompatibleBitmap(&dc, rcClient.Width(), rcClient.Height());
	CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

	// KStowell - Repaint the background.
	memDC.FillSolidRect( rcClient, ::GetSysColor(COLOR_WINDOW) );

	// let the control do its default drawing.
	CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );

	// KStowell - Copy the memory device context back into the original DC via BitBlt().
	dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC, 
		rcClip.left, rcClip.top, SRCCOPY );

	// KStowell - Cleanup resources.
	memDC.SelectObject(pOldBitmap);
	memDC.DeleteDC();
	bitmap.DeleteObject();
}